package com.cwd.arm.inter.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cwd.arm.application.dto.ProjectDetailDto;
import com.cwd.arm.application.dto.ProjectDto;
import com.cwd.arm.application.dto.confirmIncome.ProjectConfirmIncomeDto;
import com.cwd.arm.application.dto.importExccel.ProjectImportDto;
import com.cwd.arm.application.dto.project.*;
import com.cwd.arm.application.service.read.facade.ProjectReadService;
import com.cwd.arm.application.service.read.facade.UserReadService;
import com.cwd.arm.application.service.write.facade.ImportService;
import com.cwd.arm.application.service.write.facade.ProjectWriteService;
import com.cwd.arm.common.dto.session.UserDto;
import com.cwd.arm.common.enums.ExportFileEnum;
import com.cwd.arm.infrastructure.query.UserDaoQuery;
import com.cwd.arm.inter.conf.annotation.ArmAliJsonRequestBody;
import com.cwd.arm.inter.query.ProjectQuery;
import com.cwd.arm.inter.util.*;
import com.cwd.arm.inter.vo.PageVo;
import com.cwd.arm.inter.vo.ResponseVo;
import com.cwd.arm.inter.vo.cashFlow.CashFlowTotalVo;
import com.cwd.arm.inter.vo.cashFlow.ProjectCashFlowVo;
import com.cwd.arm.inter.vo.confirmIncome.ProjectConfirmIncomeVo;
import com.cwd.arm.inter.vo.project.*;
import com.cwd.arm.inter.vo.receivableAmountVo.ProjectReceivableAmountTotalVo;
import com.cwd.arm.inter.vo.receivableAmountVo.ProjectReceivableAmountVo;
import com.cwd.arm.inter.vo.receivableAmountVo.ProjectReceivePlanVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

/**
 * Description:项目
 * Created on 2021年11月16日
 *
 * @author yan
 */
@Api(value = "项目管理接口", description = "项目管理接口")
@Slf4j
@RestController
@RequestMapping(value = "/project")
public class ProjectController {

    @Autowired
    private ProjectReadService readService;

    @Autowired
    private UserReadService userReadService;

    @Autowired
    private ProjectWriteService writeService;

    @Autowired
    private ImportService importService;

    @ApiOperation(value = "查询项目详情信息", notes = "查询项目详情信息")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "id", value = "项目id", required = true, dataType = "Long", paramType = "path")
    })
    @GetMapping("/{id}")
    public ResponseVo<ProjectDetailVo> getProject(@PathVariable Long id) {
        ProjectDetailDto dto = readService.selectDetailById(id);
        return ResponseVo.<ProjectDetailVo>BUILDER().success(DtoToVoUtil.convertToDetailVo(dto));
    }

    @ApiOperation(value = "查询项目列表信息", notes = "查询项目列表信息")
    @GetMapping("/page")
    public ResponseVo<PageVo<ProjectVo>> getProjectPage(ProjectQuery projectQuery) {
        Page<ProjectDto> dtoPage = readService.selectPage(QueryToDaoQueryUtil.toDaoQuery(projectQuery));
        PageVo<ProjectVo> pageVo = new PageVo<>();
        pageVo.setRecordList(DtoToVoUtil.convertToProjectVoList(dtoPage.getRecords()));
        return ResponseVo.<PageVo<ProjectVo>>BUILDER().success(PageDtoToVoUtil.toVo(dtoPage, pageVo));
    }

    @ApiOperation(value = "导出项目列表信息", notes = "导出项目列表信息")
    @GetMapping("/export")
    public void export(ProjectQuery query, HttpServletResponse resp) throws Exception {
        List<ProjectDto> dtoList = readService.getProjectList(QueryToDaoQueryUtil.toDaoQuery(query));
        Map map = DtoToMapUtil.<ProjectDto>BUILDER().getMap(dtoList);
        ExportUtil.getInstance().exportExcel(resp, map, ExportFileEnum.PROJECT);
    }

    @ApiOperation(value = "查询所有收款人", notes = "查询所有收款人")
    @GetMapping("/ReceiveDirector")
    public ResponseVo<List<ReceiveDirectorVo>> getReceiveDirectorList() throws Exception {
        UserDaoQuery userDaoQuery = new UserDaoQuery();
        userDaoQuery.setEnabled(true);
        List<UserDto> dtoList = userReadService.selectList(userDaoQuery);
        return ResponseVo.<List<ReceiveDirectorVo>>BUILDER().success(DtoToVoUtil.convertToReceiveDirectorVoList(dtoList));
    }

    @ApiOperation(value = "查询项目应收账款列表", notes = "查询项目应收账款列表")
    @GetMapping("/receivableAmount/page")
    public ResponseVo<PageVo<ProjectReceivableAmountVo>> getReceivableAmountPage(ProjectQuery query) throws Exception {
        Page<ProjectReceivableAmountDto> dtoPage = readService.selectReceivableAmountPage(QueryToDaoQueryUtil.toDaoQuery(query));
        PageVo<ProjectReceivableAmountVo> pageVo = new PageVo<>();
        pageVo.setRecordList(DtoToVoUtil.convertToProjectReceivableAmountVoList(dtoPage.getRecords()));
        return ResponseVo.<PageVo<ProjectReceivableAmountVo>>BUILDER().success(PageDtoToVoUtil.toVo(dtoPage, pageVo));
    }


    @ApiOperation(value = "查询应收账款统计信息", notes = "查询应收账款统计信息")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "year", value = "年份", required = true, dataType = "int")
    })
    @GetMapping("/receivable/total")
    public ResponseVo<ProjectReceivableAmountTotalVo> getReceivableAmountTotal(Integer year) {
        ProjectReceivableAmountTotalDto totalDto = readService.selectReceivableAmountTotal(year);
        return ResponseVo.<ProjectReceivableAmountTotalVo>BUILDER().success(DtoToVoUtil.convertToVo(totalDto));
    }

    @ApiOperation(value = "导出项目应收账款列表", notes = "导出项目应收账款列表")
    @GetMapping("/receivable/export")
    public void exportReceivable(ProjectQuery query, HttpServletResponse resp) throws Exception {
        List<ProjectReceivableAmountDto> dtoList = readService.getReceivableAmountList(QueryToDaoQueryUtil.toDaoQuery(query));
        Integer year = query.getYear();
        ProjectReceivableAmountTotalDto totalDto = readService.selectReceivableAmountTotal(year);
        Map map = DtoToMapUtil.getReceivableAmountExcelMap(dtoList, totalDto);
        ExportUtil.getInstance().exportExcel(resp, map, ExportFileEnum.RECEIVE, year);
    }

    @ApiOperation(value = "查询项目收款计划列表", notes = "查询收款计划列表")
    @GetMapping("/receivePlan/page")
    public ResponseVo<PageVo<ProjectReceivePlanVo>> getReceivePlanPage(ProjectQuery query) throws Exception {
        Page<ProjectReceivePlanDto> dtoPage = readService.selectReceivePlanPage(QueryToDaoQueryUtil.toDaoQuery(query));
        PageVo<ProjectReceivePlanVo> pageVo = new PageVo<>();
        pageVo.setRecordList(DtoToVoUtil.convertToProjectReceivePlanVoList(dtoPage.getRecords()));
        return ResponseVo.<PageVo<ProjectReceivePlanVo>>BUILDER().success(PageDtoToVoUtil.toVo(dtoPage, pageVo));
    }

    @ApiOperation(value = "导出项目收款计划列表", notes = "导出项目收款计划列表")
    @GetMapping("/receivePlan/export")
    public void exportReceivePlan(ProjectQuery query, HttpServletResponse resp) throws Exception {
        List<ProjectReceivePlanDto> dtoList = readService.getReceivePlanList(QueryToDaoQueryUtil.toDaoQuery(query));
        Map map = DtoToMapUtil.<ProjectReceivePlanDto>BUILDER().getMap(dtoList);
        ExportUtil.getInstance().exportExcel(resp, map, ExportFileEnum.RECEIVE_PLAN);
    }

    @ApiOperation(value = "查询项目确认收入概览列表信息", notes = "查询项目确认收入概览列表信息")
    @GetMapping("/confirmIncome/page")
    public ResponseVo<PageVo<ProjectConfirmIncomeVo>> getProjectConfirmIncomePage(ProjectQuery query) throws Exception {
        Page<ProjectConfirmIncomeDto> dtoPage = readService.selectProjectConfirmIncome(QueryToDaoQueryUtil.toDaoQuery(query));
        PageVo<ProjectConfirmIncomeVo> pageVo = new PageVo<>();
        pageVo.setRecordList(DtoToVoUtil.convertTPorojectConfirmIncomeVoList(dtoPage.getRecords()));
        return ResponseVo.<PageVo<ProjectConfirmIncomeVo>>BUILDER().success(PageDtoToVoUtil.toVo(dtoPage, pageVo));
    }

    @ApiOperation(value = "导出项目确认收入概览列表信息", notes = "导出项目确认收入概览列表信息")
    @GetMapping("/confirmIncome/export")
    public void exportConfirmIncome(ProjectQuery query, HttpServletResponse resp) throws Exception {
        List<ProjectConfirmIncomeDto> dtoList = readService.getConfirmIncomeList(QueryToDaoQueryUtil.toDaoQuery(query));
        Integer year = query.getYear();
        Map map = DtoToMapUtil.getConfirmIncomeMap(dtoList);
        ExportUtil.getInstance().exportExcel(resp, map, ExportFileEnum.CONFIRM_INCOME, year);
    }

    @ApiOperation(value = "查询项目现金流列表信息", notes = "查询项目现金流列表信息")
    @GetMapping("/cashFlow/page")
    public ResponseVo<PageVo<ProjectCashFlowVo>> getProjectCashFlowPage(ProjectQuery query) {
        Page<ProjectCashFlowDto> dtoPage = readService.selectProjectCashFlowPage(QueryToDaoQueryUtil.toDaoQuery(query));
        PageVo<ProjectCashFlowVo> pageVo = new PageVo<>();
        pageVo.setRecordList(DtoToVoUtil.convertToProjectCashFlowVoList(dtoPage.getRecords()));
        return ResponseVo.<PageVo<ProjectCashFlowVo>>BUILDER().success(PageDtoToVoUtil.toVo(dtoPage, pageVo));
    }

    @ApiOperation(value = "查询现金流统计信息", notes = "查询现金流统计信息")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "year", value = "年份", required = true, dataType = "int")
    })
    @GetMapping("/cashFlow/total")
    public ResponseVo<CashFlowTotalVo> getCashFlowTotal(Integer year) {
        CashFlowTotalDto cashFlowTotalDto = readService.selectCashFlowTotal(year);
        return ResponseVo.<CashFlowTotalVo>BUILDER().success(DtoToVoUtil.convertToVo(cashFlowTotalDto));
    }

    @ApiOperation(value = "导出现金流统计信息", notes = "导出现金流统计信息")
    @GetMapping("/cashFlow/export")
    public void exportCashFlow(ProjectQuery query, HttpServletResponse resp) throws Exception {
        List<ProjectCashFlowDto> dtoList = readService.getCashList(QueryToDaoQueryUtil.toDaoQuery(query));
        Integer year = query.getYear();
        CashFlowTotalDto totalDto = readService.selectCashFlowTotal(year);
        Map map = DtoToMapUtil.getCashExcelMap(dtoList, totalDto);
        ExportUtil.getInstance().exportExcel(resp, map, ExportFileEnum.CASH, year);
    }

    @ApiOperation(value = "新增项目", notes = "新增项目")
    @Secured({"ROLE_PROJECT_ADD"})
    @PostMapping("")
    public ResponseVo<String> add(@ArmAliJsonRequestBody ProjectAddVo addVo) {
        writeService.save(VoToDtoUtil.convertToDto(addVo));
        return ResponseVo.<String>BUILDER().success();
    }

    @ApiOperation(value = "修改项目", notes = "修改项目")
    @Secured({"ROLE_PROJECT_EDIT"})
    @PutMapping("")
    public ResponseVo<String> update(@RequestBody ProjectUpdateVo updateVo) {
        writeService.update(VoToDtoUtil.convertToDto(updateVo));
        return ResponseVo.<String>BUILDER().success();
    }

    @ApiOperation(value = "删除项目", notes = "删除项目")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "id", value = "项目id", required = true, dataType = "Long", paramType = "path")
    })
    @Secured({"ROLE_PROJECT_DEL"})
    @DeleteMapping("/{id}")
    public ResponseVo<String> del(@PathVariable Long id) {
        writeService.del(id);
        return ResponseVo.<String>BUILDER().success();
    }

    @ApiOperation(value = "导入数据", notes = "通过excel导入数据")
    @Secured({"ROLE_PROJECT_IMPORT"})
    @PostMapping("/importExcel")
    public ResponseVo<String> importExcel(@RequestParam(required = true) MultipartFile file) throws Exception {
        List<ProjectImportDto> projectImportDtoList = ImportUtil.getProjectImportDtoList(file);
        importService.importProject(projectImportDtoList);
        return ResponseVo.<String>BUILDER().success();
    }

}
